Skip to content

Add helpers for StatefulSet container merging, raw ConfigMaps, and preserved Secrets#678

Merged
stuggi merged 1 commit intoopenstack-k8s-operators:mainfrom
lmiccini:drop_clusterop
Mar 31, 2026
Merged

Add helpers for StatefulSet container merging, raw ConfigMaps, and preserved Secrets#678
stuggi merged 1 commit intoopenstack-k8s-operators:mainfrom
lmiccini:drop_clusterop

Conversation

@lmiccini
Copy link
Copy Markdown
Contributor

Three new utilities to reduce boilerplate in operator controllers:

  • statefulset.MergeContainersByName: merges container specs by name, preserving server-defaulted fields (TerminationMessagePath, ImagePullPolicy, etc.) to avoid unnecessary reconcile loops. StatefulSet.CreateOrPatch now uses this instead of full Template replacement.

  • configmap.CreateOrPatchRawConfigMap: creates/patches a ConfigMap from raw map[string]string data without template rendering machinery.

  • secret.CreateOrPatchSecretPreserve: creates a Secret on first call and preserves existing Data on subsequent reconciles, useful for generated credentials that should not be rotated.

configMap.Labels = util.MergeStringMaps(configMap.Labels, lbls)
configMap.Data = data

err := controllerutil.SetControllerReference(obj, configMap, h.GetScheme())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we also allow to skip setting owner ref if needed, by passing a SkipSetOwner

}

op, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), configMap, func() error {
configMap.Labels = util.MergeStringMaps(configMap.Labels, lbls)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably good to also pass annotations, we might need it for b/r, depending on the consumer/use case

Comment on lines +210 to +213
name string,
namespace string,
data map[string]string,
lbls map[string]string,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comments on the secret func

ctx context.Context,
h *helper.Helper,
obj client.Object,
secret *corev1.Secret,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we pass a secret, in above CM case, we pass name, namespace, data, lb. should we also pass a cm for CreateOrPatchRawConfigMap ?

s.StringData = secret.StringData
}

err := controllerutil.SetControllerReference(obj, s, h.GetScheme())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above should also allow via a param to skip setting controller ref

// (e.g. TerminationMessagePath, ImagePullPolicy) and avoid
// unnecessary reconcile loops. Fall back to full replacement if
// container sets don't match by name.
if !MergeContainersByName(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we returning a bool, instead of just doing the merge?

func MergeContainersByName(existing, desired []corev1.Container) {
  ...
}
// No if statement needed. The function updates the existing object's memory.
MergeContainersByName(
    statefulset.Spec.Template.Spec.Containers,
    s.statefulset.Spec.Template.Spec.Containers,
)

@lmiccini lmiccini force-pushed the drop_clusterop branch 2 times, most recently from bc68023 to efd2f09 Compare March 31, 2026 07:35
…eserved Secrets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@stuggi stuggi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@stuggi stuggi merged commit ecff41e into openstack-k8s-operators:main Mar 31, 2026
2 checks passed
@lmiccini lmiccini deleted the drop_clusterop branch March 31, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants